#pragma once
point_2 get_point(graph_basic::lat_lon_t lat, graph_basic::lat_lon_t lon, graph_basic::lat_lon_t center_lon)
{
    return point_2(graph_basic::math::lat_lon_to_xy(lat, lon, center_lon).lat_, 
                   graph_basic::math::lat_lon_to_xy(lat, lon, center_lon).lon_);
}
point_2 get_point(graph_basic::vertex_t& v, graph_basic::lat_lon_t center_lon)
{
    return get_point(v.get_point().lat_, v.get_point().lon_, center_lon);
}
void draw_marker(viewer::viewer_dc& dc, point_2 center)
{
    dc.drawPixel(center, 6);
    //dc.drawRectangle(point_2(center.x-0.05f, center.y-0.05f), point_2(center.x+0.05f, center.y+0.05f), true);
}
void print_un_processed_adj_vertices(viewer::printer& prn, std::vector<vertex_debug_t>& vertices)
{
    std::vector<vertex_debug_t>::iterator it = vertices.begin();
    std::vector<vertex_debug_t>::iterator it_end = vertices.end();
    prn << " ";
    (prn) << "Potentials of adjacent";
    prn << "unprocessed vertices:";
    //printf("Adjacent unprocessed vertices: \n");
    for(;it != it_end; ++it)
    {
        //printf("Lat: %f \n Lon: %f \n Distance: %f \n Heuristic %f \n Potential: %f \n", 
        //    (*it).lat_, 
        //    (*it).lon_,
        //    (*it).distance_,
        //    (*it).heuristic_,
        //    (*it).distance_ + (*it).heuristic_);
        //printf("\n");
        (prn) << (*it).distance_ + (*it).heuristic_;
    }
    prn << " ";
    prn << "--------------";
}

struct bucket_draw_t
{
    bucket_draw_t()
    {
        ready_ = false;
    }
    graph_basic::graph_id_t id_;
    bool ready_; //has lines to draw
    output_list_t lines_;
    void unload()
    {
        ready_ = false;
        lines_.clear();
    }
    void load(graph_basic::graph_ptr_t graph)
    {     
        id_ = graph->get_graph_id();
        ready_ = true;
        graph_virtual::global_data_t& global = graph_virtual::global::get_instance();
        graph_basic::vertex_iterator_pair_t vertex_it_pair = graph_basic::vertices(*graph);
        for(; vertex_it_pair.first != vertex_it_pair.second; ++vertex_it_pair.first)
        {
            graph_virtual::virtual_view_adjacent_vertices_iterator_t adj_vertices = 
                  graph_virtual::adjacent_vertices((*vertex_it_pair.first).get_id(), global.current_view_);

            for(; !adj_vertices.is_empty(); ++adj_vertices)
            {
                lines_.push_back
                (
                     line_t(
                       (*vertex_it_pair.first).get_point(),
                       (*adj_vertices).get_point()
                       )
                );
            }
        }
    }
};

struct view_drawer_t
{
    view_drawer_t(viewer::viewer_dc& dc, graph_basic::graph_id_t bucket_count, size_t max_cached_bucket_count):
        buckets_(bucket_count),
        dc_(dc),
        MAX_CACHED_BUCKET_COUNT(max_cached_bucket_count),
        loaded_count_(0),
        prev_path_type_(graph_basic::PATH_TYPE_ALL)
    {
        for(graph_basic::graph_int_t i = 0; i < bucket_count; ++i)
        {
            buckets_[i].id_ = i;
        }
    }
    void draw_view(graph_basic::lat_lon_t lat_view_square_center, graph_basic::lat_lon_t lon_view_square_center, graph_basic::lat_lon_t center_lon)
    {
        graph_virtual::global_data_t& global = graph_virtual::global::get_instance();
        if (prev_path_type_ != global.current_path_type_)
        {
            for(graph_basic::graph_int_t i = 0; i < buckets_.size(); ++i)
            {
                buckets_[i].unload();
            }
            prev_path_type_ = global.current_path_type_;
        }
        buckets_t::iterator it = buckets_.begin();
        buckets_t::iterator end = buckets_.end();
        graph_basic::point_t buck_sq = graph_virtual::details::virtual_graph_friend_t::get_bucket_square_size(*global.graph_);
        graph_basic::lat_lon_t lat_square = buck_sq.lat_*static_cast<int>(sqrt((float)MAX_CACHED_BUCKET_COUNT));
        graph_basic::lat_lon_t lon_square = buck_sq.lon_*static_cast<int>(sqrt((float)MAX_CACHED_BUCKET_COUNT));;
        for(; it != end; ++it)
        {
            graph_basic::details::graph_inf_t& b_info = 
               graph_virtual::details::virtual_graph_friend_t::get_bucket_info(*global.graph_, it->id_);
            if ( (b_info.min_lat_ > (lat_view_square_center - lat_square) && 
                  b_info.min_lon_ > (lon_view_square_center - lon_square)) &&
                 (b_info.max_lat_ < (lat_view_square_center + lat_square) && 
                  b_info.max_lon_ < (lon_view_square_center + lon_square)) )
            {
                if ((*it).ready_)
                {
                    draw_bucket((*it).id_,center_lon);
                }
                else
                {
                    //if (loaded_count_ <= MAX_BUCKET_COUNT)
                    //if ( (*it).id_<50 || (*it).id_ > 65 )
                    {
                       if (loaded_count_ > MAX_CACHED_BUCKET_COUNT)
                       {
                           --loaded_count_;
                           unload_suitable_bucket();
                       }
                       ++loaded_count_;
                       (*it).load(
                           graph_virtual::details::virtual_graph_friend_t::get_bucket
                           (*global.graph_, (*it).id_).get_graph_ptr()
                        );
                       draw_bucket((*it).id_,center_lon);
                    }
                }
            }
            else
            //draw simple square
            {
                if (b_info.vertex_count_ > 0)
                    draw_square(b_info.min_lat_, b_info.min_lon_, b_info.max_lat_, b_info.max_lon_, center_lon);
            }
        }
    }
    void unload_suitable_bucket()
    {
        buckets_[rand() % MAX_CACHED_BUCKET_COUNT].unload();
    }
    void draw_bucket(graph_basic::graph_id_t buck_id, graph_basic::lat_lon_t center_lon)
    {        
        bucket_draw_t& buck = buckets_[buck_id];
        output_list_t::iterator it = buck.lines_.begin();
        output_list_t::iterator end = buck.lines_.end();
        for(; it != end; ++it)
        {
            dc_.drawLine(
                    get_point((*it).first.lat_, (*it).first.lon_, center_lon),
                    get_point((*it).second.lat_, (*it).second.lon_, center_lon),
                    1
                );
        }
    }
    void draw_square(graph_basic::lat_lon_t min_lat, graph_basic::lat_lon_t min_lon, 
                     graph_basic::lat_lon_t max_lat, graph_basic::lat_lon_t max_lon, 
                     graph_basic::lat_lon_t center_lon)
    {
        dc_.drawLine(
                get_point(min_lat, min_lon, center_lon),
                get_point(max_lat, max_lon, center_lon)
            );
        dc_.drawLine(
                get_point(min_lat, max_lon, center_lon),
                get_point(max_lat, min_lon, center_lon)
            );
    }
private:
    typedef std::vector<bucket_draw_t> buckets_t;
    graph_basic::graph_int_t const MAX_CACHED_BUCKET_COUNT;
    std::string prev_path_type_;
    buckets_t buckets_;
    viewer::viewer_dc& dc_;
    graph_basic::graph_int_t loaded_count_;
};


void draw_astar_sh_path(viewer::viewer_dc& dc, astar_search_t<debug, undirectional>& as, graph_basic::lat_lon_t center_lon)
{
    graph_virtual::global_data_t& global = graph_virtual::global::get_instance();
    dc.setColor(colorf(0.0f, 0.0f, 1.0f));
    graph_basic::vertex_id_t finish_id = as.get_finish_vertex_id();
    graph_basic::vertex_id_t start_id = as.get_start_vertex_id();
    graph_basic::vertex_id_t temp_id = as.get_finish_vertex_id();
    graph_basic::vertex_id_t temp_prev_id = as.get_finish_vertex_id();
    
    vertex_data_container_t<astar_vertex_data_t>& vert_data = as.get_vertex_data();
    while (temp_id != start_id)
    {
        graph_basic::vertex_t& temp_v = global.graph_->get_vertex_by_id(temp_id);
        graph_basic::vertex_t& temp_prev_v = global.graph_->get_vertex_by_id(temp_prev_id);
        dc.drawLine(get_point(temp_v, center_lon), get_point(temp_prev_v.get_point().lat_, temp_prev_v.get_point().lon_, center_lon) );
        temp_prev_id = temp_id;
        temp_id = vert_data.get_value(temp_id).predecessor_;
    }
}
void draw_astar_sh_path(viewer::viewer_dc& dc, astar_search_t<debug, bidirectional>& as, graph_basic::lat_lon_t center_lon)
{
    vertex_data_container_t<astar_vertex_data_t> dim1_v_data = as.get_vertex_data();
    vertex_data_container_t<astar_vertex_data_t> dim2_v_data = as.get_vertex_data2();
    
    graph_virtual::global_data_t& global = graph_virtual::global::get_instance();
    dc.setColor(colorf(0.0f, 0.0f, 1.0f));
    graph_basic::vertex_id_t finish_id = as.get_finish_vertex_id();
    graph_basic::vertex_id_t start_id = as.get_start_vertex_id();
    graph_basic::vertex_id_t temp_id = as.get_fwd_search_cur_vertex_id();
    graph_basic::vertex_id_t temp_prev_id = as.get_fwd_search_cur_vertex_id();

    while (temp_id != start_id)
    {
        graph_basic::vertex_t& temp_v = global.graph_->get_vertex_by_id(temp_id);
        graph_basic::vertex_t& temp_prev_v = global.graph_->get_vertex_by_id(temp_prev_id);
        dc.drawLine(get_point(temp_v, center_lon), get_point(temp_prev_v.get_point().lat_, temp_prev_v.get_point().lon_, center_lon) );
        temp_prev_id = temp_id;
        temp_id = dim1_v_data.get_value(temp_id).predecessor_;
    }
    dc.drawLine(
        get_point( global.graph_->get_vertex_by_id(temp_prev_id) , center_lon), 
        get_point( global.graph_->get_vertex_by_id(temp_id), center_lon) 
        );   
    temp_id = as.get_bkwd_search_cur_vertex_id();
    temp_prev_id = as.get_bkwd_search_cur_vertex_id();
    while (temp_id != finish_id)
    {
        graph_basic::vertex_t& temp_v = global.graph_->get_vertex_by_id(temp_id);
        graph_basic::vertex_t& temp_prev_v = global.graph_->get_vertex_by_id(temp_prev_id);
        dc.drawLine(get_point(temp_v, center_lon), get_point(temp_prev_v.get_point().lat_, temp_prev_v.get_point().lon_, center_lon) );
        temp_prev_id = temp_id;
        temp_id = dim2_v_data.get_value(temp_id).predecessor_;
    }
    dc.drawLine(
        get_point( global.graph_->get_vertex_by_id(temp_prev_id) , center_lon), 
        get_point( global.graph_->get_vertex_by_id(temp_id), center_lon) 
        ); 
    dc.drawLine(
        get_point( global.graph_->get_vertex_by_id(as.get_fwd_search_cur_vertex_id()) , center_lon), 
        get_point( global.graph_->get_vertex_by_id(as.get_bkwd_search_cur_vertex_id()), center_lon) 
        );    
}
void draw_astar(viewer::viewer_dc& dc, astar_search_t<debug, undirectional>& as, graph_basic::lat_lon_t center_lon)
{
    graph_virtual::global_data_t& global = graph_virtual::global::get_instance();

    dc.setColor(colorf(0.7f, 0.7f, 0.7f)); // grey
    graph_basic::vertex_t& start = global.graph_->get_vertex_by_id(as.get_start_vertex_id());
    graph_basic::vertex_t& finish = global.graph_->get_vertex_by_id(as.get_finish_vertex_id());

    draw_marker(dc, get_point(start, center_lon));
    draw_marker(dc, get_point(finish, center_lon));

    //showing visited vertices
    dc.setColor(colorf(1.0f, 0.8f, 0.0f)); //orange
    output_list_t& o_list = as.get_output_list();
    output_list_t::iterator it = o_list.begin();
    output_list_t::iterator it_end = o_list.end();
    //a_edge back;
    for(; it!=it_end; ++it)
    {
        dc.drawLine(
            get_point((*it).first.lat_, (*it).first.lon_, center_lon),
            get_point((*it).second.lat_,(*it).second.lon_, center_lon),
            1
            );
        //back = (*it);
    }


    
    dc.setColor(colorf(0.7f, 0.7f, 0.7f)); //grey
    draw_marker(dc, get_point(as.deb_vertex_prev1_.lat_, as.deb_vertex_prev1_.lon_, center_lon));
    dc.setColor(colorf(1.0f, 0.8f, 0.0f)); //orange 
    draw_marker(dc, get_point(as.deb_vertex_current1_.lat_, as.deb_vertex_current1_.lon_, center_lon));    

    viewer::printer prn(dc, point_2i(10, 50));
    dc.setTextColor(colorf(1.0f, 0.8f, 0.0f)); //orange 
    prn << " ";
    prn << "Summary: ";
    prn << "--------------";
    prn << " ";
    prn << "Iteration: ";
    prn << as.num_iterates_;
    prn << "visited_vertices: ";
    prn << as.visited_vertices_;
    prn << "visited edges: ";
    prn << as.visited_edges_;
    prn << " ";
    prn << "--------------";
    prn << " ";
    dc.setTextColor(colorf(0.7f, 0.7f, 0.7f)); //grey
    prn << "Previous vertex:";
    prn << "Distance:";
    prn << as.deb_vertex_prev1_.distance_;
    prn << "Potential:";
    prn << as.get_potential(as.deb_vertex_prev1_.id_, true);
    //prn << "Dist + Potential:";
    //prn << as.deb_vertex_prev1_.distance_ + as.deb_vertex_prev1_.heuristic_;
    print_un_processed_adj_vertices(prn, as.deb_vertex_prev1_adj);

    dc.setTextColor(colorf(1.0f, 0.8f, 0.0f)); //orange 
    prn << "Current vertex:";
    prn << "Distance:";
    prn << as.deb_vertex_current1_.distance_;
    //prn << "Heuristic:";
    //prn << as.deb_vertex_current1_.heuristic_;
    prn << "Potential:";
    prn << as.get_potential(as.deb_vertex_current1_.id_, true);

    dc.setTextColor(colorf(1.0f, 1.0f, 1.0f)); //white 
    prn << "Sub routine calls:";
    prn << "Opened list 1 change priority:";
    prn << as.opened_list1_chpriority_calls_;
    prn << "Opened list 1 extract min:";
    prn << as.opened_list1_extract_min_calls_;
    prn << "Opened list 1 is in:";
    prn << as.opened_list1_isin_calls_;
    prn << "Opened list 1 max elems:";
    prn << as.opened_list1_max_elems_;
    prn << "Opened list 1 put:";
    prn << as.opened_list1_put_calls_;
    prn << "Closed list 1 is in:";
    prn << as.closed_list1_isin_calls_;
    prn << "Closed list 1 put:";
    prn << as.closed_list1_put_calls_;
    prn << "Put predecessor 1:";
    prn << as.put_predecessor_calls_;
    prn << "Get distance 1:";
    prn << as.get_distance_calls_;
    
    // if astar ended, draw shortest path
    if (as.is_all_ended())
        draw_astar_sh_path(dc, as, center_lon);

}
void draw_astar(viewer::viewer_dc& dc, astar_search_t<debug, bidirectional>& as, graph_basic::lat_lon_t center_lon)
{
    graph_virtual::global_data_t& global = graph_virtual::global::get_instance();
    
    dc.setColor(colorf(0.7f, 0.7f, 0.7f)); // grey
    graph_basic::vertex_t& start = global.graph_->get_vertex_by_id(as.get_start_vertex_id());
    graph_basic::vertex_t& finish = global.graph_->get_vertex_by_id(as.get_finish_vertex_id());

    draw_marker(dc, get_point(start, center_lon));
    draw_marker(dc, get_point(finish, center_lon));

    //showing visited vertices
    dc.setColor(colorf(1.0f, 0.8f, 0.0f)); // orange
    output_list_t& o_list = as.get_output_list();
    output_list_t::iterator it = o_list.begin();
    output_list_t::iterator it_end = o_list.end();
    line_t back;
    for(; it!=it_end; ++it)
    {
        dc.drawLine(
            get_point((*it).first.lat_, (*it).first.lon_, center_lon),
            get_point((*it).second.lat_,(*it).second.lon_, center_lon),
            1
            );
        back = (*it);
    }
    draw_marker(dc, get_point(back.second.lat_, back.second.lon_, center_lon));
    //showing visited vertices
    dc.setColor(colorf(0.0f, 0.8f, 1.0f)); //light blue
    output_list_t& o_list2 = as.get_output_list2();
    it = o_list2.begin();
    it_end = o_list2.end();
    for(; it!=it_end; ++it)
    {
        dc.drawLine(
            get_point((*it).first.lat_, (*it).first.lon_, center_lon),
            get_point((*it).second.lat_,(*it).second.lon_, center_lon),
            1
            );
        back = (*it);
    }
    draw_marker(dc, get_point(back.second.lat_, back.second.lon_, center_lon));
    //showing sh path
    //dc.setColor(colorf(0.0f, 0.0f, 1.0f));
    ////graph_basic::vertex_id_t temp_id = mid_id;
    //graph_basic::vertex_id_t start_id = as.start_vertex_id_;
    //graph_basic::vertex_id_t finish_id = as.finish_vertex_id_;
    //
    //std::vector<graph_basic::vertex_id_t>& predecessors = as.GetPredecessors();
    //std::vector<graph_basic::vertex_id_t>& predecessors2 = as.GetPredecessors2();

    //int counter = 200;
    //while(temp_id != start_id)// && counter)
    //{
    //    dc.drawLine(
    //        get_point(graph_virtual::global.graph_->GetVertexByIndex(temp_id)),
    //        get_point(graph_virtual::global.graph_->GetVertexByIndex(predecessors[temp_id])),
    //        3
    //        );
    //    temp_id = predecessors[temp_id];
    //    //--counter;
    //}
    //temp_id = mid_id;
    //counter = 100;
    //while(temp_id != finish_id)// && counter)
    //{
    //    dc.drawLine(
    //        get_point(graph_virtual::global.graph_->GetVertexByIndex(temp_id)),
    //        get_point(graph_virtual::global.graph_->GetVertexByIndex(predecessors2[temp_id])),
    //        3
    //        );
    //    temp_id = predecessors2[temp_id];
    //    //--counter;
    //}
    // first direction of search and summary
    viewer::printer prn(dc, point_2i(10, 50));
    dc.setTextColor(colorf(1.0f, 0.8f, 0.0f)); //orange 
    prn << " ";
    prn << "Summary: ";
    prn << "--------------";
    prn << " ";
    prn << "Iteration: ";
    prn << as.num_iterates_;
    prn << "visited_vertices: ";
    prn << as.visited_vertices_;
    prn << "visited edges: ";
    prn << as.visited_edges_;
    prn << " ";
    prn << "--------------";
    prn << " ";
    dc.setTextColor(colorf(0.7f, 0.7f, 0.7f)); //grey
    prn << "Previous vertex:";
    prn << "Distance:";
    prn << as.deb_vertex_prev1_.distance_;
    prn << "Potential:";
    prn << as.get_potential(as.deb_vertex_prev1_.id_, true);;
    //prn << "Dist + potential:";
    //prn << as.deb_vertex_prev1_.distance_ + as.deb_vertex_prev1_.heuristic_;
    print_un_processed_adj_vertices(prn, as.deb_vertex_prev1_adj);

    dc.setTextColor(colorf(1.0f, 0.8f, 0.0f)); //orange 
    prn << "Current vertex:";
    prn << "Distance:";
    prn << as.deb_vertex_current1_.distance_;
    prn << "Potential:";
    prn << as.get_potential(as.deb_vertex_current1_.id_, true);
    //prn << "Dist + potential:";
    //prn << as.deb_vertex_current1_.distance_ + as.deb_vertex_current1_.heuristic_;

    dc.setTextColor(colorf(1.0f, 1.0f, 1.0f)); //white 
    prn << "Sub routine calls:";
    prn << "Opened list 1 change priority:";
    prn << as.opened_list1_chpriority_calls_;
    prn << "Opened list 1 extract min:";
    prn << as.opened_list1_extract_min_calls_;
    prn << "Opened list 1 is in:";
    prn << as.opened_list1_isin_calls_;
    prn << "Opened list 1 max elems:";
    prn << as.opened_list1_max_elems_;
    prn << "Opened list 1 put:";
    prn << as.opened_list1_put_calls_;
    prn << "Closed list 1 is in:";
    prn << as.closed_list1_isin_calls_;
    prn << "Closed list 1 put:";
    prn << as.closed_list1_put_calls_;
    prn << "Put predecessor 1:";
    prn << as.put_predecessor_calls_;
    prn << "Get distance 1:";
    prn << as.get_distance_calls_;

    // second direction of search
    viewer::printer prn2(dc, point_2i(1000, 50));
    dc.setTextColor(colorf(0.0f, 0.8f, 1.0f)); //orange
    prn2 << " ";
    prn2 << "Summary: ";
    prn2 << "--------------";
    prn2 << " ";
    prn2 << "Iteration: ";
    prn2 << as.num_iterates2_;
    prn2 << "visited_vertices: ";
    prn2 << as.visited_vertices2_;
    prn2 << "visited edges: ";
    prn2 << as.visited_edges2_;
    prn2 << " ";
    prn2 << "--------------";
    prn2 << " ";
    dc.setTextColor(colorf(0.7f, 0.7f, 0.7f)); //grey
    prn2 << "Previous vertex:";
    prn2 << "Potential:";
    prn2 << as.deb_vertex_prev2_.distance_;
    //prn2 << "Heuristic:";
    //prn2 << as.deb_vertex_prev2_.heuristic_;
    prn2 << "Potential:";
    prn << as.get_potential(as.deb_vertex_prev2_.id_, false);
    print_un_processed_adj_vertices(prn2, as.deb_vertex_prev2_adj);

    dc.setTextColor(colorf(0.0f, 0.8f, 1.0f)); //orange
    prn2 << "Current vertex:";
    prn2 << "Potential:";
    prn2 << as.deb_vertex_current2_.distance_;
    //prn2 << "Heuristic:";
    //prn2 << as.deb_vertex_current2_.heuristic_;
    prn2 << "Potential:";
    prn << as.get_potential(as.deb_vertex_current2_.id_, false);
    
    // if astar ended, draw shortest path
    if (as.is_all_ended())
        draw_astar_sh_path(dc, as, center_lon);
}
graph_basic::vertex_id_t get_nearest_vertex_id(graph_basic::lat_lon_t global_x, graph_basic::lat_lon_t global_y, graph_basic::lat_lon_t center_lon)
{
    graph_virtual::global_data_t& global = graph_virtual::global::get_instance();

    graph_basic::lat_lon_t target_lat = graph_basic::math::xy_to_lat_lon(global_x, global_y, center_lon).lat_;
    graph_basic::lat_lon_t target_lon = graph_basic::math::xy_to_lat_lon(global_x, global_y, center_lon).lon_;

    graph_basic::graph_id_t target_id =
       graph_virtual::details::virtual_graph_friend_t::find_bucket(*global.graph_, graph_basic::point_t(target_lat, target_lon));
    graph_basic::graph_view_ptr_t view = global.get_current_view_for_graph(
        graph_virtual::details::virtual_graph_friend_t::get_bucket(*global.graph_, target_id).get_graph_ptr()
    );
    
    graph_basic::view_vertex_iterator_pair_t iters  = graph_basic::vertices(*view);

    if (!(iters.first != iters.second))
    {
        std::cerr << "WARNING!" << std::endl 
            << "There is no vertices (filtered by view) in specified bucket. Using random." << std::endl;
        throw std::exception("There is no vertices (filtered by view) in specified bucket");
    }

    graph_basic::lat_lon_t nearest_dist = graph_basic::MAX_FLOAT;
    graph_basic::lat_lon_t temp_dist = graph_basic::MAX_FLOAT;
    graph_basic::vertex_id_t nearest_vertex_id(0, 0);
    for(; iters.first != iters.second; ++iters.first)
    {
        temp_dist = graph_basic::math::distance(
            (*iters.first).get_point().lat_,
            (*iters.first).get_point().lon_,
            target_lat,
            target_lon
            );
        if (temp_dist < nearest_dist)
        {
            nearest_dist = temp_dist;
            nearest_vertex_id = (*iters.first).get_id();
        }
    }
    return nearest_vertex_id;
}
//now we print it to console
template<astar_direction_e direction>
void print_vertex_info(graph_basic::vertex_id_t id, astar_search_t<debug, direction>& as, viewer::viewer_dc& dc, graph_basic::lat_lon_t center_lon)
{
    graph_virtual::global_data_t& global = graph_virtual::global::get_instance();
    dc.setColor(colorf(0.0f,0.0f,1.0f));
    vertex_debug_t v = as.get_debug_vertex_by_id(id, true);
    draw_marker(dc, get_point(v.lat_, v.lon_, center_lon));
    
    viewer::printer prn(dc, point_2i(1000, dc.screenViewport()[1].hi() - 140));
    dc.setTextColor(colorf(1.0f, 1.0f, 1.0f)); //white
    prn << "Latitude: ";
    prn << v.lat_;
    prn << "Longtitude: ";
    prn << v.lon_;
    prn << "Distance: ";
    prn << v.distance_;
    prn << "Potential: ";
    prn << as.get_potential(v.id_, true);
    //prn << "Potential+Distance: ";
    //prn << v.heuristic_ + v.distance_;
    if(direction == bidirectional)
    {
        viewer::printer prn(dc, point_2i(800, dc.screenViewport()[1].hi() - 155));
        dc.setTextColor(colorf(1.0f, 1.0f, 1.0f)); //white
        v = as.get_debug_vertex_by_id(id, false);
        prn << "Second dimension: ";
        prn << "Latitude: ";
        prn << v.lat_;
        prn << "Longtitude: ";
        prn << v.lon_;
        prn << "Distance: ";
        prn << v.distance_;
        prn << "Potential: ";
        prn << as.get_potential(v.id_, true);
        //prn << "Potential+Distance: ";
        //prn << v.heuristic_ + v.distance_;
    }
}